import React from 'react';
import isFunction from "lodash-es/isFunction";
import {omit, map, pick, forEach, isEmpty, isObject} from 'lodash-es'
import PropTypes from 'prop-types';
import {QueryTable} from "../QueryTable";
import {queryCateApi} from "../Config/GlobalApi";
import {Col, Row} from "antd";
import TreeComp from "../TreeComp/TreeComp";
import {getRandomKey, QueryFilter, recursiveMap} from "jh-utils";
import {connect} from "dva";

/**
 * 用于带“搜索条件、左侧有树状分类”的查询列表
 */
export class QueryTreeTable extends QueryTable {

    static propTypes = {
        ...QueryTable.propTypes,
        /**
         * 分类配置，对应 ./config 的配置（在 界面设计器 配置）
         * @type {[{remark: string, name: string}]}
         */
        cateConf: PropTypes.arrayOf(PropTypes.object),
        /**
         * 请求“左侧分类列表”数据
         * @type {function(cateSelNode: {}):Promise}
         * @param cateSelNode {{}} 左侧选中的节点
         * Promise 返回的第一个参数，即列表数据
         */
        fetchCateList: PropTypes.func
    };

    /**
     * 左侧分类树组件的实例
     * @type {TreeComp | undefined}
     */
    treeIns;

    /**
     * 左侧分类树的数据类型
     * @type {'obj' | 'tree' | 'boolean' | 'enum' | 'normal' | ''}
     */
    cateType = '';
    /**
     * 当前组件的唯一key。
     * 用于绑定各类事件等
     * @type {string}
     */
    compRandomKey = getRandomKey();

    initState(props) {
        return {
            ...super.initState(props),
            cateLoading: false, // 是否正在加载“左侧分类树”
            cateList: [], // “左侧分类树”数据
        }
    }

    componentDidMount() {
        super.componentDidMount();
        // 添加“保存详情之后的回调函数”
        this.runAppinsFunc('addAfterSaveCb')(this.compRandomKey, this.hdlAfterSave.bind(this));
    }

    componentWillUnmount() {
        super.componentWillUnmount();
        // 移除“保存详情之后的回调函数”
        this.runAppinsFunc('removeAfterSaveCb')(this.compRandomKey);
    }

    /**
     * 保存详情之后的回调。
     * - 保存详情之后，如果左侧分类不是“树类型”数据，则刷新左侧分类树的数据
     * @param rsp {{status: number, data: any} | undefined | null}
     */
    hdlAfterSave(rsp) {

        if (rsp && 200 === rsp.status) {
            let cateField = this.getCateField();
            let cateType = this.cateType;
            if (cateField && 'tree' !== cateType) {
                this.fetchCateList();
            }
        }
    }

    /**
     * 获取“左侧分类树作为筛选条件时”的字段名
     * @return {string}
     */
    getCateField() {
        let cateConf = this.props.cateConf;
        let cateField = '';

        if (!isEmpty(cateConf) && cateConf[0] && cateConf[0].name) {
            cateField = cateConf[0].name;
        }
        return cateField;
    }

    /**
     * 是否第一次请求。
     * 是的话，fetchList 时，会先请求分类列表，再请求表格列表。
     * 否则，fetchList 时，只请求表格列表。
     * @type {boolean}
     */
    isFirstFetch = true;

    fetchList() {
        if (this.isFirstFetch) {
            this.isFirstFetch = false;
            this.fetchCateList();
            //     .then(() => {
            //     // super.fetchList();
            // });
        }
        // else {
        // }
        super.fetchList();
    }

    /**
     * 请求获取“左侧分类列表”
     */
    fetchCateList() {
        return new Promise((resolve) => {
            let appCode = this.getAppCode();
            let cateField = this.getCateField();
            console.log('fetchCateList cateField', cateField);

            if (isEmpty(cateField)) {
                resolve();
                return;
            }

            const {fetchCateList} = this.props;
            let fetchFunc = isFunction(fetchCateList) ? fetchCateList : this._fetchCateFunc.bind(this);

            if (isFunction(fetchFunc)) {

                this.setState({cateLoading: true});

                const funcReturn = fetchFunc({appCode, cateField});

                if (funcReturn instanceof Promise) {
                    funcReturn.then(rsp => {
                        const newState = {cateLoading: false};

                        if (rsp && rsp.status === 200) {
                            const rspData = rsp.data;
                            if (!isEmpty(rspData)) {
                                let cateList;

                                if (isObject(rspData)) {
                                    this.cateType = rspData.type;
                                    cateList = [rspData];
                                } else {
                                    this.cateType = '';
                                    cateList = rspData;
                                }
                                if (cateList && cateList[0]) {
                                    cateList[0].isRoot = true; // 标识是 根节点
                                }
                                newState.cateList = recursiveMap(cateList, (dItem) => {
                                    const obj = {
                                        ...dItem,
                                        key: dItem.id || dItem.code || dItem.type || dItem.name,
                                        title: dItem.name
                                    };
                                    return obj;
                                });
                            }
                        }
                        this.setState(newState);
                        resolve(rsp);
                    });
                    return;
                }
                this.setState({cateLoading: false});
            }
            resolve();
        });

    }

    _fetchCateFunc(ajaxData) {
        return this.reqGet(queryCateApi.api, ajaxData);
    }


    /**
     * 选择节点之后的回调
     * @param keys {string[]} 选中的节点
     * @param event {{selected: boolean, selectedNodes, node, event}}
     */
    hdlSelectNode(keys, {node}) {
        let cateType = this.cateType;
        let cateField = this.getCateField();
        console.log('hdlSelectNode node', node);

        if (undefined === this.searchData.filterData) {
            this.searchData.filterData = {};
        }

        if (cateField) {
            let cateVal;
            switch (cateType) {
                case "obj":
                case "tree":
                    cateVal = node.id;
                    cateField = `${cateField}.id`;
                    break;
                case "enum":
                    cateVal = node.code;
                    break;
                case "boolean":
                    cateVal = node;
                    break;
                default:
                    cateVal = node;
            }

            if (undefined !== cateVal && null !== cateVal) {
                this.searchData.filterData[cateField] = {expression: QueryFilter.EQUAL, value: cateVal};
            } else {
                delete this.searchData.filterData[cateField];
            }
        } else {
            delete this.searchData.filterData[cateField];
        }
        console.log('qtt hdlSelectNode this.searchData', this.searchData);
        this.fetchList();
    }

    getTableHeight() {
        return '100%';
    }

    listRender(context) {
        let {style} = this.props;
        let compHeight = style && style.height ? style.height : '600px';
        let rowHeight = 'auto' === compHeight ? 'auto' : `calc(100% - ${this.searchHeight}px)`;

        return (
            <Row style={{flexFlow: 'nowrap', height: rowHeight}}>
                <Col flex={'250px'} style={{paddingBottom: 8}}>
                    <TreeComp
                        style={{height: '100%'}}
                        border={true}
                        loading={this.state.cateLoading}
                        compData={this.state.cateList}
                        onRef={(ref) => {
                            this.treeIns = ref;
                        }}
                        isSearch={false}
                        afterSelect={this.hdlSelectNode.bind(this)}
                    />
                </Col>
                <Col flex={'auto'} style={{paddingLeft: '8px', overflow: 'auto'}}>
                    {
                        super.listRender(context)
                    }
                </Col>
            </Row>
        )
    }

}

export default connect(({queryTable}) => ({queryTable}))(QueryTreeTable);